/*  This file is part of LibGChart.
 *
 * AUTHORS
 *       Sascha Dewald        <sascha.dewald@googlemail.com>
 *
 * Copyright (C) 2009 Sascha Dewald
 *
 *  
 *  
 *  LibGChart is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Foobar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with LibGChart.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

using System;

using Cairo;

namespace LibGChart
{
	/**
	 * class GCaption 
	 */
	public class GCaption
	{
		private string text = string.Empty;
		private double yBearing;		// Same as the Height
		private double height, width;
		private double heightHalf, widthHalf;
		private int fontSize;
		private int fontSpace;
		
		private double posParallel, posUpright;
		
		private Color color;
		
		internal double rotation = 0.0;
	
		// Will be called if the Size or Text changed
		internal event DelegateOnChanged OnTextChanged;
		internal event DelegateOnChanged OnFontSizeChanged;
		internal event DelegateOnChanged OnFontSpaceChanged;
		internal event DelegateOnChanged OnPosParallelChanged;
		internal event DelegateOnChanged OnPosUprightChanged;
		
		internal event DelegateOnChanged OnWidthChanged;
		internal event DelegateOnChanged OnHeightChanged;
		internal event DelegateOnChanged OnYBearingChanged;
		
		/**
		 * default constructor
		 */
		public GCaption()
		{
			color = new Color(1.0, 1.0, 1.0);
		}
		
		/**
		 * Property Text, gets/sets the text of the caption
		 */
		public string Text {
			get { return text; }
			
			set {
				if (text.CompareTo(value) != 0)
				{
					text = value;
					
					calc_extents();
					
					if (OnTextChanged != null)
						OnTextChanged();
				}
			}
		}
		
		/**
		 * Property YBearing, represent the Space between top of the font, and the drawing start pos
		 */
		public double YBearing
		{
			get {
				return yBearing;
			}
		}
		
		/**
		 * Property Height, represent the height of the text
		 */
		public double Height
		{
			get {
				return height;
			}
		}
		
		/**
		 * Property Width, represent the width of the text
		 */
		public double Width
		{
			get {
				return width;
			}
		}
		
		/**
		 * Property HeightHalf, represent the half height of the text
		 */
		public double HeightHalf
		{
			get {
				return heightHalf;
			}
		}
		
		/**
		 * Property WidthHalf, represent the half width of the text
		 */
		public double WidthHalf
		{
			get {
				return widthHalf;
			}
		}
		
		/**
		 * Property FontSize, gets/sets the Size of the Font
		 */
		public int FontSize
		{
			get {
				return fontSize;
			}
			
			set {
				if (fontSize != value)
				{
					fontSize = value;
					
					calc_extents();
					
					if (OnFontSizeChanged != null)
						OnFontSizeChanged();
				}
			}
		}
		
		/**
		 * Property FontSpace, gets/sets the space around the Text
		 */
		public int FontSpace
		{
			get {
				return fontSpace;
			}
			
			set {
				if (fontSpace != value)
				{
					fontSpace = value;
					
					if (OnFontSpaceChanged != null)
						OnFontSpaceChanged();
				}
			}
		}
		
		/**
		 * the Color of the Caption
		 */
		internal Color Color
		{
			get { return color; }
		}
		
		/**
		 * Property PosX, represent the real Position of the Caption
		 */
		internal double PosParallel
		{
			get { return posParallel; }
			set {
				if (posParallel != value)
				{
					posParallel = value;
					
					if (OnPosParallelChanged != null)
						OnPosParallelChanged();
				}
				    
			}
		}

		/**
		 * Property PosY, represent the real Position of the Caption
		 */
		internal double PosUpright
		{
			get { return posUpright; }
			set {
				if (posUpright != value)
				{
					posUpright = value;
					
					if (OnPosUprightChanged != null)
						OnPosUprightChanged();
				}
				    
			}
		}
		
		/**
		 * public function set_color, set the color of the chart
		 */
		public void set_color(double r, double g, double b)
		{
			color = new Color(r, g, b);
		}
		
		/**
		 * internal function calc_extents, Calculate the width and height of the Text
		 */
		private void calc_extents()
		{
			Cairo.TextExtents extents;
			
			Cairo.Context cr = OffScreenContextHelper.OffscreenContext;
			
			cr.Save();
				
			cr.SetFontSize(fontSize);
			extents = cr.TextExtents(text);
			
			if (width != extents.Width)
			{
				width = extents.Width;
				widthHalf = width / 2.0;
				
				if (OnWidthChanged != null)
					OnWidthChanged();
			}
			
			if (height != extents.Height)
			{
				height = extents.Height;
				heightHalf = height / 2.0;
				
				if (OnHeightChanged != null)
					OnHeightChanged();
			}
			
			if (yBearing != extents.YBearing)
			{
				yBearing = extents.YBearing;
				
				if (OnYBearingChanged != null)
					OnYBearingChanged();
			}
			
			cr.Restore();
		}
		
		/**
		 * internal function draw, draws the chart
		 */
		internal void draw(Context cr)
		{
			// Save the State of the Graphics Context
			//cr.Save();
			
			// Set font Color
			cr.Color = color;
			cr.SetFontSize(fontSize);
			cr.MoveTo(posParallel, posUpright);
			cr.Rotate(rotation);
			cr.ShowText(text);
			
			// Restore the State of the Graphics Context
			//cr.Restore();
		}
	}
}
